﻿using System;
using System.Collections.Generic;
using System.Linq;
using HHPS.CreditEducation.DataProvider;
using HHPS.CreditEducation.Frameworks.Commons;
using HHPS.CreditEducation.Frameworks.Constants;

namespace HHPS.CreditEducation.Business
{
    public partial class Business
    {
        #region -- Get Faculty --

        /// <summary>
        /// This function shows list of faculties.
        /// </summary>
        /// <returns></returns>
        public List<Faculty> GetListFacutly()
        {
            return DataContex != null ? DataContex.Faculties.ToList() : null;
        }

        #endregion

        #region Common

        private static bool FacultyCommonValidator(Faculty faculty, out string message)
        {
            if (string.IsNullOrWhiteSpace(faculty.Name))
            {
                message = string.Format(ConstantMessages.RequireFieldIsBlank, "tên Khoa");
                return false;
            }

            if (faculty.Name.Length >= 50)
            {
                message = string.Format(ConstantMessages.FieldDataOverMaxLength, "tên Khoa", 50);
                return false;
            }
            message = string.Empty;
            return true;
        }

        #endregion

        #region -- Add Faculty --

        /// <summary>
        /// This function check validate of add a new facutly function
        /// </summary>
        /// <param name="faculty"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddNewFacultyValidator(Faculty faculty, out string message)
        {
            if (!FacultyCommonValidator(faculty, out message)) return false;

            if (DataContex.Faculties.Any(f => f.Name.ToLower() == faculty.Name.ToLower()))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, faculty.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function add a new facutly into list.
        /// </summary>
        public void AddNewFaculty(Faculty faculty)
        {
            DataContex.Faculties.AddObject(faculty);
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Edit Faculty --

        /// <summary>
        /// This function check validate of edit a facutly function
        /// </summary>
        /// <param name="faculty"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool EditFacultyValidator(Faculty faculty, out string message)
        {
            var id = faculty.Id;
            if (!DataContex.Faculties.Any(f => f.Id == id))
            {
                message = ConstantMessages.CanNotIdentifyItem;
                return false;
            }

            if (!FacultyCommonValidator(faculty, out message)) return false;

            if (DataContex.Faculties.Any(f => f.Name.ToLower() == faculty.Name.ToLower() && f.Id != id))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, faculty.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function edits a facutly
        /// </summary>
        /// <param name="faculty"></param>
        public bool EditFaculty(Faculty faculty)
        {
            var id = faculty.Id;
            var updateFaculty = DataContex.Faculties.SingleOrDefault(f => f.Id == id);

            if (updateFaculty == null)
                return false;

            updateFaculty.Name = faculty.Name;

            DataContex.SaveChanges();
            return true;
        }

        #endregion

        #region -- Delete Faculty --

        /// <summary>
        /// This function check validate of delete list of facutlies function
        /// </summary>
        /// <param name="faculties"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool DeleteFacultiesValidator(IEnumerable<Faculty> faculties, out string message)
        {
            const string intialize = "Khoa: ";
            var itemsCannotIdentify = (from faculty in faculties
                                       let id = faculty.Id
                                       where !DataContex.Faculties.Any(f => f.Id == id)
                                       select faculty).Aggregate(intialize, (current, faculty) => current + (faculty.Name + ", "));

            if (itemsCannotIdentify != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsCanNotIdentify, itemsCannotIdentify.TrimEnd(','));
                return false;
            }

            var itemsInUse = (from faculty in faculties
                              let id = faculty.Id
                              where DataContex.Majors.Any(m => m.IdFaculty == id)
                              select faculty).Aggregate(intialize, (current, faculty) => current + (faculty.Name + ", "));

            if (itemsInUse != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsInUseCanNotDelete, itemsInUse.TrimEnd(','));
                return false;
            }

            message = string.Empty;
            return true;
        }

        /// <summary>
        /// Delete object
        /// </summary>
        public void DeleteFaculties(List<Faculty> faculties)
        {
            for (var i = faculties.Count - 1; i >= 0; i--)
            {
                var id = faculties[i].Id;
                var deleteFaculty = DataContex.Faculties.Single(f => f.Id == id);
                DataContex.Faculties.DeleteObject(deleteFaculty);
            }
            DataContex.SaveChanges();
        }

        #endregion

        public void AddOrUpdateUser(User user)
        {
            var updateUser = DataContex.Users.FirstOrDefault();
            if (updateUser == null)
            {
                DataContex.Users.AddObject(user);
            }
            else
            {
                updateUser.Name = user.Name;
                updateUser.MoreInformation = user.MoreInformation;
                updateUser.Birthday = user.Birthday;
                updateUser.Picture = user.Picture;
                updateUser.IdFaculty = user.IdFaculty;
                updateUser.IdMajor = user.IdMajor;
            }
            DataContex.SaveChanges();
        }
    }
}